package jaxb.metagrammar;

import java.util.Collection;
import java.util.Set;

import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import metagrammar.Operator;
import metagrammar.Transform;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;

/**
 * Adapts a {@link LinkedHashMultimap} for use by {@link JAXB}
 * @author Joshua Lockerman
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
public class OperatorAdaptedLinkedHashMultimap {
    
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class MultimapEntry {
        
        private MultimapEntry()
        {
            transform = new Transform[] {};
        }
        
        public MultimapEntry(Operator key, Collection<Transform> values)
        {
            target = key;
            transform = values.toArray(new Transform[values.size()]);
        }
        
        @XmlJavaTypeAdapter(OperatorToUUIDStringAdapter.class)
        @XmlAttribute
        private Operator target;
        
        @XmlElement
        private final Transform[] transform;
        
        public Operator getKey()
        {
            return target;
        }
        
        public ImmutableList<Transform> getValues()
        {
            return ImmutableList.copyOf(transform);
        }
    }
    
    @XmlElement
    private final MultimapEntry[] entries;
    
    @SuppressWarnings("unchecked")
    private OperatorAdaptedLinkedHashMultimap()
    {
        entries = new MultimapEntry[] {};
    }
    
    @SuppressWarnings("unchecked")
    public OperatorAdaptedLinkedHashMultimap(Multimap<Operator, Transform> v)
    {
        Set<Operator> keySet = v.keySet();
        entries = new MultimapEntry[keySet.size()];
        int i = 0;
        for(Operator key : keySet) {
            MultimapEntry mutiMapEntry = new MultimapEntry(key, v.get(key));
            entries[i] = mutiMapEntry;
            i++;
        }
    }
    
    public ImmutableList<MultimapEntry> getEntries()
    {
        return ImmutableList.copyOf(entries);
    }
}
